package com.fortune.rainshineservice.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.fortune.rainshinecommon.model.*;
import com.fortune.rainshinecommon.model.system.CardModel;
import com.fortune.rainshinecommon.util.DateUtils;
import com.fortune.rainshineservice.mapper.*;
import com.fortune.rainshineservice.service.StatService;
import com.google.common.collect.Lists;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Optional;

/**
 * @program: rainShine
 * @description: 统计报表定时任务
 * @author: tangyn
 * @create: 2019-05-17
 **/
@Component
@EnableScheduling
public class StatTask {
    private static final Logger logger = LoggerFactory.getLogger(StatTask.class);

    private final ShopMapper shopMapper;
    private final DayProductStatMapper dayProductStatMapper;
    private final ProductMapper productMapper;
    private final DayShopStatMapper dayShopStatMapper;
    private final MonthProductStatMapper monthProductStatMapper;
    private final MonthShopStatMapper monthShopStatMapper;
    private final CardMapper cardMapper;
    private final DayServiceStatMapper dayServiceStatMapper;
    private final MonthServiceStatMapper monthServiceStatMapper;
    private final StatService statService;

    @Autowired
    public StatTask(ShopMapper shopMapper, DayProductStatMapper dayProductStatMapper, ProductMapper productMapper,
                    DayShopStatMapper dayShopStatMapper, MonthProductStatMapper monthProductStatMapper,
                    StatService statService, MonthShopStatMapper monthShopStatMapper, CardMapper cardMapper,
                    DayServiceStatMapper dayServiceStatMapper, MonthServiceStatMapper monthServiceStatMapper) {
        this.shopMapper = shopMapper;
        this.dayProductStatMapper = dayProductStatMapper;
        this.productMapper = productMapper;
        this.dayShopStatMapper = dayShopStatMapper;
        this.monthProductStatMapper = monthProductStatMapper;
        this.statService = statService;
        this.monthShopStatMapper = monthShopStatMapper;
        this.cardMapper = cardMapper;
        this.dayServiceStatMapper = dayServiceStatMapper;
        this.monthServiceStatMapper = monthServiceStatMapper;
    }

    @Bean
    public TaskScheduler taskScheduler() {
        ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
        taskScheduler.setPoolSize(50);
        return taskScheduler;
    }

    @Async
    @Scheduled(cron = "0 0 0 * * ? ") //每天零点
//    @Scheduled(cron = "0 45 21 * * ? ") //测试
    public void dayStat() {
        logger.info("0点执行统计任务--------------------------------------------------------");
        //获取上次统计的日期
        Date startDate = shopMapper.getMinStatDate();
        Date endDate = new Date();
        List<String> dateList = DateUtils.getDates(startDate, endDate);
        for(String date : dateList){
            statService.stateDayShop(date);
        }
        //产品进销存日统计
        for(String date : dateList){
            statService.statDayProduct(date);
        }
        //门店服务次数日统计
        for(String date : dateList){
            statService.statDayService(date);
        }
        //修改商铺表的统计时间
        Wrapper<ShopModel> wrapper = new EntityWrapper<>();
        wrapper.eq("shop_status", 1);
        List<ShopModel> shopModelList = Optional.ofNullable(shopMapper.selectList(wrapper)).orElse(Lists.newArrayList());
        for(ShopModel s : shopModelList){
            s.setStatDate(endDate);
            shopMapper.updateById(s);
        }
        logger.info("执行每日统计全部完成--------------------------------------------------------");
    }

    @Async
    @Scheduled(cron = "0 0 2 2 * ? ") //每月2号2点
//    @Scheduled(cron = "0 0 14 31 * ? ") //测试
    public void monthStat() {
        logger.info("每月的统计开始执行--------------------------------------------------------");
        Date startDate = shopMapper.getMinStatMonth();
        if(startDate == null){
            String lastYearMonth = DateUtils.getLastMonth();
            startDate = DateUtils.parse(lastYearMonth+"-01", null);
        }
        //比较两个月月差
        int betweenNum = DateUtils.timeBetweenMonth(new DateTime(startDate), DateTime.now());
        DateTime lastMonthDate = new DateTime(startDate);
        for (int i = 0; i < betweenNum; i++) {
            Date statDate = DateUtils.parse(DateUtils.format(lastMonthDate.toDate(),DateUtils.YYYY_MMM_DD), null);
            statService.monthShopStat(statDate, lastMonthDate);
            statService.monthProductStat(statDate, lastMonthDate);
            statService.monthServiceStat(statDate, lastMonthDate);
            lastMonthDate = lastMonthDate.plusMonths(1);
        }
        Wrapper<ShopModel> wrapper = new EntityWrapper<>();
        wrapper.eq("shop_status", 1);
        List<ShopModel> shopModelList = Optional.ofNullable(shopMapper.selectList(wrapper)).orElse(Lists.newArrayList());
        for(ShopModel s : shopModelList){
            s.setStatMonth(lastMonthDate.dayOfMonth().withMinimumValue().toDate());
            shopMapper.updateById(s);
        }
        logger.info("执行每月统计全部完成--------------------------------------------------------");
        //获取所有营业的店铺列表
//        Wrapper<ShopModel> wrapper = new EntityWrapper<>();
//        wrapper.eq("shop_status", 1);
//        List<ShopModel> shopModelList = Optional.ofNullable(shopMapper.selectList(wrapper)).orElse(Lists.newArrayList());
//        if (!shopModelList.isEmpty()) {
//            shopModelList.forEach(e -> {
//                //获取上一次月统计的日期
//                Date lastMonthTime = shopMapper.getTheLastMonthTime(e.getId());
//                if(lastMonthTime == null){
//                    String lastYearMonth = DateUtils.getLastMonth();
//                    lastMonthTime = DateUtils.parse(lastYearMonth+"-01", null);
//                }
//                //比较两个月月差
//                int betweenNum = DateUtils.timeBetweenMonth(new DateTime(lastMonthTime), DateTime.now());
//                DateTime lastMonthDate = new DateTime(lastMonthTime);
//                for (int i = 0; i < betweenNum; i++) {
////                    Integer year = lastMonthDate.getYear();
////                    Integer month = lastMonthDate.getMonthOfYear();
//                    Date statDate = DateUtils.parse(DateUtils.format(lastMonthDate.toDate(),DateUtils.YYYY_MMM_DD), null);
//                    try{
////                        monthShopStat(e, year, month, statDate);
////                        monthProductStat(e, year, month, statDate);
////                        monthServiceStat(e, year, month, statDate);
//                        statService.monthShopStat(statDate, lastMonthDate);
//                        statService.monthProductStat(statDate, lastMonthDate);
//                        statService.monthServiceStat(statDate, lastMonthDate);
//                    }catch (Exception ex){
//                        logger.error("monthStat ====> {}", ex);
//                        lastMonthDate = lastMonthDate.plusMonths(1);
//                        continue;
//                    }
//                    lastMonthDate = lastMonthDate.plusMonths(1);
//                }
//                //更新shop表的stat_date
//                e.setStatMonth(lastMonthDate.dayOfMonth().withMinimumValue().toDate());
//                shopMapper.updateById(e);
//            });
//        }
    }

    private void monthServiceStat(ShopModel shopModel, Integer year, Integer month, Date statDate) {
        Wrapper<CardModel> cardWrapper = new EntityWrapper<>();
        cardWrapper.eq("is_active", 1);
        List<CardModel> cardModelList = Optional.ofNullable(cardMapper.selectList(cardWrapper)).orElse(Lists.newArrayList());
        if (!cardModelList.isEmpty()) {
            cardModelList.forEach(e -> {
                Wrapper<DayServiceStatModel> wrapper = new EntityWrapper<>();
                wrapper.eq("shop_id", shopModel.getId());
                wrapper.eq("service_type", e.getId());
                wrapper.eq("stat_year", year);
                wrapper.eq("stat_month", month);
                List<DayServiceStatModel> dsmList = Optional.ofNullable(dayServiceStatMapper.selectList(wrapper)).orElse(Lists.newArrayList());
                if (!dsmList.isEmpty()) {
                    int n = 0; //服务次数
                    for (DayServiceStatModel d : dsmList) {
                        n += d.getServiceTimes();
                    }

                    MonthServiceStatModel model = new MonthServiceStatModel();
                    model.setShopId(shopModel.getId());
                    model.setShopLevel(shopModel.getShopLevel());
                    model.setServiceType(e.getId());
                    model.setServiceTimes(n);
                    model.setStatYear(year);
                    model.setStatMonth(month);
                    model.setStatDate(statDate);
                    model.setCreateTime(new Date());
                    monthServiceStatMapper.insert(model);
                }
            });
        }
    }

    private void monthShopStat(ShopModel shopModel, Integer year, Integer month, Date statDate) {
        Wrapper<DayShopStatModel> wrapper = new EntityWrapper<>();
        wrapper.eq("shop_id", shopModel.getId());
        wrapper.eq("stat_year", year);
        wrapper.eq("stat_month", month);
        List<DayShopStatModel> dsmList = Optional.ofNullable(dayShopStatMapper.selectList(wrapper)).orElse(Lists.newArrayList());
        if (!dsmList.isEmpty()) {
            int n = 0;//新增会员数
            int s = 0;//服务总次数
            BigDecimal buyTotal = BigDecimal.ZERO;
            BigDecimal saleTotal = BigDecimal.ZERO;
            for (DayShopStatModel i : dsmList) {
                n += i.getNewCount();
                s += i.getServerTimes();
                if (i.getBuyTotalPrice() != null) {
                    buyTotal = buyTotal.add(i.getBuyTotalPrice());
                }
                if (i.getSaleTotalPrice() != null) {
                    saleTotal = saleTotal.add(i.getSaleTotalPrice());
                }
            }
            MonthShopStatModel model = new MonthShopStatModel();
            model.setShopId(shopModel.getId());
            model.setShopLevel(shopModel.getShopLevel());
            model.setNewCount(n);
            model.setServerTimes(s);
            model.setBuyTotalPrice(buyTotal);
            model.setSaleTotalPrice(saleTotal);
            model.setStatYear(year);
            model.setStatMonth(month);
            model.setStatDate(statDate);
            model.setCreateTime(new Date());
            monthShopStatMapper.insertSelective(model);
        }
    }

    private void monthProductStat(ShopModel shopModel, Integer year, Integer month, Date statDate) {
        Wrapper<ProductModel> pw = new EntityWrapper<>();
        pw.eq("sale_status", 1);
        List<ProductModel> pmList = Optional.ofNullable(productMapper.selectList(pw)).orElse(Lists.newArrayList());
        if (!pmList.isEmpty()) {
            for (ProductModel e : pmList) {
                try {
                    monthStatByType(shopModel, year, month, e, 1, statDate);//采购入库
                    monthStatByType(shopModel, year, month, e, 2, statDate);//采购出库
                    monthStatByType(shopModel, year, month, e, 3, statDate);//门店销售
                    monthStatByType(shopModel, year, month, e, 4, statDate);//门店领用
                } catch (Exception ex) {
                    continue;
                }
            }
        }
    }

    private void monthStatByType(ShopModel shopModel, Integer year, Integer month, ProductModel pm, int statType, Date statDate) {
        Wrapper<DayProductStatModel> wrapper = new EntityWrapper<>();
        wrapper.eq("shop_id", shopModel.getId());
        wrapper.eq("product_id", pm.getId());
        wrapper.eq("stat_year", year);
        wrapper.eq("stat_month", month);
        wrapper.eq("stat_type", statType); //1:入库，2：出库，3：销售，4：领用
        List<DayProductStatModel> inputList = Optional.ofNullable(dayProductStatMapper.selectList(wrapper)).orElse(Lists.newArrayList());
        if (!inputList.isEmpty()) {
            int q = 0;//产品数量
            BigDecimal p = BigDecimal.ZERO;//产品总价
            for (DayProductStatModel i : inputList) {
                q += i.getQuantity();
                if (i.getTotalPrice() != null) {
                    p = p.add(i.getTotalPrice());
                }
            }
            MonthProductStatModel model = new MonthProductStatModel();
            model.setShopId(shopModel.getId());
            model.setShopLevel(shopModel.getShopLevel());
            model.setProductId(pm.getId());
            model.setQuantity(q);
            model.setTotalPrice(p);
            model.setStatType(statType);
            model.setStatYear(year);
            model.setStatMonth(month);
            model.setStatDate(statDate);
            model.setCreateTime(new Date());
            monthProductStatMapper.insert(model);
        }
    }

    public static void main(String[] args) {
        System.out.println(DateUtils.getLastMonth());
    }

}
